package io.lvdaxian.map4.file.stream.common.file;

import io.lvdaxian.map4.file.stream.common.CommonUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FileUtils {
  /**
   * 创建目录事件
   *
   * @param dirPath 目录名称
   * @author lihh
   */
  public static void mkDir(String dirPath) {
    File dirPathFile = new File(dirPath);
    
    // 判断目录是否存在
    if (!(dirPathFile.exists() && dirPathFile.isDirectory()))
      dirPathFile.mkdir();
  }
  
  /**
   * 获取文件名称 不包括后缀
   *
   * @param filename 文件名称
   * @return 文件名称 不包括后缀
   * @author lihh
   */
  public static String getNameExcludeExt(String filename) {
    if (null == filename) return null;
    
    int idx = filename.length() - 1;
    for (; idx >= 0; idx -= 1) {
      char c = filename.charAt(idx);
      if ('.' == c) break;
    }
    
    return -1 == idx ? filename : filename.substring(0, idx);
  }
  
  /**
   * 删除存在的目录 以及文件
   *
   * @param fileOrDirPath 文件或是目的地址
   * @author lihh
   */
  public static void deleteIfExists(String fileOrDirPath) {
    File file = new File(fileOrDirPath);
    
    if (!file.exists()) return;
    
    if (file.isFile()) file.delete();
    else {
      File[] files = file.listFiles();
      if (null == files) return;
      
      for (File fileItem : files) {
        if (fileItem.isDirectory())
          deleteIfExists(fileItem.getPath());
        fileItem.delete();
      }
      
      file.delete();
    }
  }
  
  /**
   * 删除目录列表，只删除列表，不包括目录本身
   *
   * @param dirPath 目录地址
   * @author lihh
   */
  public static void deleteDirectoryListing(String dirPath) {
    File file = new File(dirPath);
    
    if (!file.exists() || !file.isDirectory()) return;
    
    File[] files = file.listFiles();
    if (null == files) return;
    
    for (File item : files)
      item.delete();
  }
  
  /**
   * 多个 path 拼接
   *
   * @param paths 多个目录
   * @return 返回拼接的 url
   * @author lihh
   */
  public static String joinPath(String... paths) {
    if (null == paths || 0 == paths.length) return "";
    boolean firstWordSymbol = paths[0].startsWith("/"),
        lastWordSymbol = paths[paths.length - 1].endsWith("/");
    
    List<String> pathList = Arrays.stream(paths).map(path -> {
      
      if (path.startsWith("/")) path = path.replaceAll("^/+", "");
      if (path.endsWith("/")) path = path.replaceAll("/+$", "");
      
      return path;
    }).collect(Collectors.toList());
    
    return (firstWordSymbol ? File.separator : "")
        + String.join(File.separator, pathList)
        + (lastWordSymbol ? File.separator : "");
  }
  
  /**
   * 读取文件列表
   *
   * @param dirPath 目录地址
   * @return 返回目录列表
   * @author lihh
   */
  public static File[] readDirectoryListing(String dirPath) {
    File file = new File(dirPath);
    
    if (!file.isDirectory()) return null;
    File[] files = file.listFiles();
    if (null == files || files.length == 0) return null;
    
    // 为了防止文件顺序乱了 这里进行强制排序
    CommonUtils.tmpFileSort(files, r -> ((File) r).getName());
    return files;
  }
  
  /**
   * 判断文件是否存在
   *
   * @param filePath 文件路径
   * @return 返回 boolean 状态
   * @author lihh
   */
  public static boolean isFileExist(String filePath) {
    return new File(filePath).isFile();
  }
  
  /**
   * 写文件的事件
   *
   * @param outputFilePath 输出的文件地址
   * @param inputStream    输入流
   * @author lihh
   */
  public static void writeFile(String outputFilePath, InputStream inputStream) {
    try {
      OutputStream outputStream = Files.newOutputStream(Paths.get(outputFilePath));
      
      byte[] buffer = new byte[1024];
      int length;
      while ((length = inputStream.read(buffer)) > 0) {
        outputStream.write(buffer, 0, length);
      }
      
      outputStream.close();
      inputStream.close();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
}
